package red.internal.core.message;

import red.internal.core.id.SingleSnowflakeId;
import red.internal.core.util.Constant;

/**
 * @author Jin Zheng
 * @date 2020-05-13
 */
public class Message
{
	private Protocol protocol;
	private Version version;
	private Direction direction;
	private long messageId;
	private long eventId;
	private Code code;
	private String message;

	public Message()
	{
	}

	protected static <T extends Message> T create(Protocol protocol)
	{
		T request = protocol.getMessage();
		request.setProtocol(protocol);
		request.setVersion(Constant.DEFAULT_VERSION);
		request.setDirection(Direction.SEND);
		request.setMessageId(SingleSnowflakeId.getInstance().nextId());
		request.setEventId(request.getMessageId());
		request.setCode(Code.SUCCESS);
		return request;
	}

	public final <T extends Message> T success()
	{
		return this.toResponse(true, Constant.SUCCESS_MESSAGE);
	}

	public final <T extends Message> T success(String message)
	{
		return this.toResponse(true, message);
	}

	public final <T extends Message> T failure(String message)
	{
		return this.toResponse(false, message);
	}

	protected <T extends Message> T toResponse(boolean success, String message)
	{
		return this.createResponse(message);
	}

	protected final <T extends Message> T createResponse(String message)
	{
		T response = protocol.getMessage();
		response.setProtocol(protocol);
		response.setVersion(version);
		response.setDirection(Direction.RECEIVE);
		response.setMessageId(SingleSnowflakeId.getInstance().nextId());
		response.setEventId(eventId);
		response.setCode(Code.SUCCESS);
		response.setMessage(message);
		return response;
	}

	public void setProtocol(int protocol)
	{
		this.protocol = Protocol.valueOf(protocol);
	}

	public void setVersion(int version)
	{
		this.version = Version.valueOf(version);
	}

	public void setDirection(int version)
	{
		this.direction = Direction.valueOf(version);
	}

	public void setCode(int code)
	{
		this.code = Code.valueOf(code);
	}

	public Protocol getProtocol()
	{
		return protocol;
	}

	public void setProtocol(Protocol protocol)
	{
		this.protocol = protocol;
	}

	public Version getVersion()
	{
		return version;
	}

	public void setVersion(Version version)
	{
		this.version = version;
	}

	public Direction getDirection()
	{
		return direction;
	}

	public void setDirection(Direction direction)
	{
		this.direction = direction;
	}

	public long getMessageId()
	{
		return messageId;
	}

	public void setMessageId(long messageId)
	{
		this.messageId = messageId;
	}

	public long getEventId()
	{
		return eventId;
	}

	public void setEventId(long eventId)
	{
		this.eventId = eventId;
	}

	public Code getCode()
	{
		return code;
	}

	public void setCode(Code code)
	{
		this.code = code;
	}

	public String getMessage()
	{
		return message;
	}

	public void setMessage(String message)
	{
		this.message = message;
	}
}
